import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

public class MainFrame extends JFrame {
    private Client client;
    private Panel panel = new Panel();
    private Button button = new Button("Send request");
    private JTextField textfield = new JTextField();
    private JTable tableau;
    private JTextArea text;
    private Object[][] data;

    public MainFrame(Client client) {
        this.client = client;
	this.setTitle("P2P aight");
	this.setSize(800, 530);
	this.setLocationRelativeTo(null);
	this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Action à la fermeture
        this.addWindowListener(new WindowAdapter(){
            @Override
		public void windowClosing(WindowEvent e){
                MainFrame.this.client.closeToTracker();
            }
	    });

        button.addActionListener(new ButtonListener());
	//*
        Update up = new Update(client.getSocketTracker(), client.getOut(),
			       client.getIn());
        up.start();
	/* */
	//*
        //Envoi de la commande look pour actualiser la liste de fichiers
        client.sendToTracker("look []");
        String answerToLook = client.receiveFromTracker();
        treatmentLookAnswer(answerToLook);
	/* */
        String title[] = {"Nom", "Taille", "Clé"};
	tableau = new JTable(new DefaultTableModel(data, title));
        tableau.getColumnModel().getColumn(0).setPreferredWidth(240);
        tableau.getColumnModel().getColumn(2).setPreferredWidth(350);
        tableau.getColumn("Nom").setCellEditor(new ButtonEditor(new JCheckBox()));
        tableau.getColumn("Nom").setCellRenderer(new ButtonRenderer());

        JLabel label = new JLabel("Réponses du Tracker", JLabel.CENTER);

        Font police = new Font("Arial", Font.PLAIN, 12);
        text = new JTextArea();
        text.setFont(police);
        text.setForeground(Color.LIGHT_GRAY);
        text.setBackground(Color.DARK_GRAY);
        text.setLineWrap(true);
        text.setWrapStyleWord(true);

        police = new Font("Arial", Font.BOLD, 14);
        textfield.setFont(police);
        textfield.setForeground(Color.BLUE);

        JPanel sspanel1 = new JPanel();

        sspanel1.setLayout(new BorderLayout());
        sspanel1.add(label, BorderLayout.NORTH);
        sspanel1.add(text, BorderLayout.CENTER);

        JPanel sspanel2 = new JPanel();

        sspanel2.setLayout(new BorderLayout());
        sspanel2.add(sspanel1, BorderLayout.CENTER);
        sspanel2.add(new JScrollPane(tableau), BorderLayout.WEST);

        JPanel sspanel3 = new JPanel();

        sspanel3.setLayout(new BorderLayout());
        sspanel3.add(textfield, BorderLayout.CENTER);
        sspanel3.add(button, BorderLayout.EAST);

        panel.setLayout(new BorderLayout());
	panel.add(sspanel2, BorderLayout.CENTER);
	panel.add(sspanel3, BorderLayout.SOUTH);

	this.setContentPane(panel);
	this.setVisible(true);
    }

    private void ActualiseAffichage(String answer) {
        treatmentLookAnswer(answer);
        DefaultTableModel model = ((DefaultTableModel) tableau.getModel());
        //On efface le tableau
        while (model.getRowCount() != 0)
            model.removeRow(0);
        //On le reremplit ligne après ligne
        for (int i = 0 ; i<data.length ; i++)
            model.addRow(data[i]);
    }

    private void treatmentLookAnswer(String answer) {
        String [] answerTable = answer.substring(0, answer.length() - 1).
	    substring(6).split(" ");
        data = new Object[answerTable.length/4][3];
        int k;
        for (int i = 0 ; i<answerTable.length/4 ; i++) {
            k = 0;
            for (int j = 0 ; j<3 ; j++, k++) {
                if (j == 2)
                    k++;
                if (j == 0) {
                    data[i][j] = answerTable[4*i+k];
                }
                else {
                    data[i][j] = answerTable[4*i+k];
                }
            }
        }
    }

    //écoute bouton 1
    class ButtonListener implements ActionListener {

        @Override
	    public void actionPerformed(ActionEvent act) {
            //Envoi de la requête au Tracker
            String request = textfield.getText();
            client.sendToTracker(request);

            //Affichage de la réponse du Tracker
            String answer = client.receiveFromTracker();
            text.setText(answer);

            //Envoi de la commande look pour actualiser la liste de fichiers
            client.sendToTracker("look []");
            String answerToLook = client.receiveFromTracker();

            if (answerToLook.contains("list")) {
                ActualiseAffichage(answerToLook);
            }
            else if (answerToLook.contains("ok")
		     || answerToLook.contains("\n")
		     || answerToLook.isEmpty()) {
                System.err.println("Problème de réponse du Tracker");
            }
            else {
                System.err.println("Problème de réponse du Tracker");
                System.exit(-1);
            }

            //Remise à zéro de la zone de commande
            textfield.setText("");
	}
    }
    
    class ButtonEditor extends DefaultCellEditor {

        protected JButton button;
        private boolean isPushed;
        private ButtonListener bListener = new ButtonListener();

        public ButtonEditor(JCheckBox checkBox) {
            super(checkBox);
            button = new JButton();
            button.setOpaque(true);
            button.addActionListener(bListener);
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value,
        boolean isSelected, int row, int column) {

            bListener.setRow(row);
            bListener.setColumn(column);
            bListener.setTable(table);

            button.setText( (value ==null) ? "" : value.toString() );
            return button;
        }

        class ButtonListener implements ActionListener{

            private int column, row;
            private JTable table;
            private int nbre = 0;

            public void setColumn(int col) {this.column = col;}
            public void setRow(int row) {this.row = row;}
            public void setTable(JTable table) {this.table = table;}

            @Override
            public void actionPerformed(ActionEvent event) {
                client.sendGetfile(table.getValueAt(row, 2).toString());
                String answer = client.receiveFromTracker();
                System.out.println("Réponse tracker : " + answer);
            }
        }
    }
}

class Panel extends JPanel {

    private int c = 20;

    @Override
	public void paintComponent(Graphics g) {
	g.setColor(new Color(c, c, c));
	g.fillRect(0, 0, this.getWidth(), this.getHeight());
    }
}

class Button extends JButton implements MouseListener {

    private int c = 50;
    private int c2 = 220;
    private String name;
    private Font font = new Font("Arial", Font.PLAIN, 13);

    Button(String name) {
	super(name);
	this.name = name;
	this.addMouseListener(this);
    }

    @Override
	public void paintComponent(Graphics g) {
	g.setColor(new Color(c, c, c));
	g.fillRect(0, 0, this.getWidth(), this.getHeight());

        g.setColor(new Color(c2, c2, c2));
	g.setFont(font);
	g.drawString(name, 25, 17);
    }

    @Override
	public void mouseClicked(MouseEvent event) {
    }
    @Override
	public void mouseEntered(MouseEvent event) {
    }
    @Override
	public void mouseExited(MouseEvent event) {
    }
    @Override
	public void mousePressed(MouseEvent event) {
    }
    
    @Override
	public void mouseReleased(MouseEvent event) {
	// mouse out of button surface
	if (event.getY() < 0
	    || event.getX() < 0
	    || event.getY() > this.getHeight()
	    || event.getX() > this.getWidth()) {

	}
	else {

	}
    }
}

class ButtonRenderer extends JButton implements TableCellRenderer {

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value,
    boolean isSelected, boolean isFocus, int row, int col) {
        setText((value != null) ? value.toString() : "");
	return this;
    }
}
/*
class MyTableModel extends AbstractTableModel{

    private Object[][] data;
    private String[] title;

    public MyTableModel(Object[][] data, String[] title){
        this.data = data;
        this.title = title;
    }

    @Override
    public int getColumnCount() {
        return this.title.length;
    }

    @Override
    public int getRowCount() {
        return this.data.length;
    }

    @Override
    public String getColumnName(int col) {
        return this.title[col];
    }

    @Override
    public Class getColumnClass(int col){
    return this.data[0][col].getClass();
    }

    @Override
    public Object getValueAt(int row, int col) {
        return this.data[row][col];
    }

    public void removeRow(int position){
        int indice = 0, indice2 = 0, nbRow = this.getRowCount()-1, nbCol = this.getColumnCount();
        Object temp[][] = new Object[nbRow][nbCol];

        for(Object[] value : this.data){
            if(indice != position){
                temp[indice2++] = value;
            }
            System.out.println("Indice = " + indice);
            indice++;
        }
        this.data = temp;
        this.fireTableDataChanged();
    }

    public void addRow(Object[] data){
        int indice = 0, nbRow = this.getRowCount(), nbCol = this.getColumnCount();

        Object temp[][] = this.data;
        this.data = new Object[nbRow+1][nbCol];

        for(Object[] value : temp)
            this.data[indice++] = value;

        this.data[indice] = data;
        this.fireTableDataChanged();
    }

    @Override
    public boolean isCellEditable(int row, int col){
            return false;
    }
}
/*
class TableComponent extends DefaultTableCellRenderer {

    @Override
    public Component getTableCellRendererComponent(JTable table,Object value,
    boolean isSelected, boolean hasFocus, int row, int column) {

        if (value instanceof JButton) {
            return (JButton) value;
	    }
        else {
            return this;
	    }
    }
}
/* */
